package com.baizhi.service.impl;

import com.baizhi.dao.CmfzAdminDao;
import com.baizhi.entity.CmfzAdmin;
import com.baizhi.service.CmfzAdminService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.UUID;

@Service
@Slf4j
public class CmfzAdminServiceImpl implements CmfzAdminService {
    @Autowired
    private CmfzAdminDao cmfzAdminDao;
    @Override
    @Transactional(readOnly = true)
    public Page<CmfzAdmin> selectPage(Integer page, Integer limit) {
        //创建分页对象   封装分页数据信息
        Page<CmfzAdmin> cmfzAdminPage = new Page<>(page, limit);
        //调用分页查询方法
        Page<CmfzAdmin> selectPage = cmfzAdminDao.selectPage(cmfzAdminPage, null);
        return selectPage;
    }

    @Override
    /*
    * 添加管理员的方法   这里采用shiro封装的加密工具类加密保存密码
    * 所以此时需要对页面收到的密码进行加密处理（底层shiro框架封装了）
    * 但需要提供一个随机的盐值salt  将其和页面收参的明文password一起进行加密处理
    * 并且向数据库中保存的实际数据是：账号和加密后的密文、以及随机生成的盐值
    * */
    public void insertCmfzAdmin(CmfzAdmin cmfzAdmin) {
        //1、将页面收到的参数（这里用的对象收参）中的明文密码拿出来
        String password = cmfzAdmin.getPassword();//明文密码
        //2、随机生成一个字符串  作为盐值
        String salt = UUID.randomUUID().toString().substring(0, 4);//随机一个4位的字符串
        //3、利用shiro的加密工具类进行加密处理（加密和散列）
        /*参数1：页面收到的明文密码
        * 参数2：随机生成的盐值
        * 参数3：散列次数（要加密的次数）
        * */
        Md5Hash hash = new Md5Hash(password, salt, 1024);
        //获取加密后的密文
        String hex = hash.toHex();
        //4、将盐值和密文封装到管理员对象中
        cmfzAdmin.setPassword(hex);
        cmfzAdmin.setSalt(salt);
        log.info("要添加管理员信息："+cmfzAdmin);
        //5、调用管理员的添加数据库方法
        cmfzAdminDao.insert(cmfzAdmin);
    }

    @Override
    @Transactional(readOnly = true)
    public CmfzAdmin login(String username, String password) {
        //构造查询条件对象
        QueryWrapper<CmfzAdmin> queryWrapper = new QueryWrapper<>();
        //封装查询条件
        queryWrapper.eq("username",username).eq("password",password);
        //调用查询方法
        CmfzAdmin cmfzAdmin = cmfzAdminDao.selectOne(queryWrapper);
        return cmfzAdmin;
    }

    @Override
    @Transactional(readOnly = true)
    //集成shiro后的登陆方法（shiro认证）
    public boolean shiroLogin(String username, String password) {
        //shiro认证
//        1、将页面传来的账号和密码封装到token令牌中
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
//        2、获取Subject对象
        Subject subject = SecurityUtils.getSubject();
//        3、调用subject的login方法     认证失败抛异常 返回false
        try {
            subject.login(token);
            return true;
        } catch (AuthenticationException e) {
            e.printStackTrace();
            return false;
        }
    }
}
